package com.study.subpub;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * @Author HBZ
 * @Date 2020/7/21 15:48
 * @Description 订阅器类
 */
public class SubscribePublish<M> {
    //订阅器名称
    private String name;
    //订阅器队列容量
    final int QUEUE_CAPACITY = 5;
    //订阅器存储队列
    private BlockingQueue<Msg> queue = new ArrayBlockingQueue<Msg>(QUEUE_CAPACITY);
    //订阅者
    private List<ISubcriber> subcribers = new ArrayList<>();
    /**
     * @Description:构造方法
     * @param name
     */
    public SubscribePublish(String name) {
        this.name = name;
    }
    /**
     * @Description: 接收发布者的消息
     * @param publisherName
     * @param message
     * @param isInstantMsg
     * @author: leijing
     * @date: 2016年9月29日 下午5:17:03
     */
    public void publish(String publisherName,M message,boolean isInstantMsg) {
        // 直接发送，不存入队列
        if(isInstantMsg){
            update(publisherName,message);
            return;
        }
        Msg<M> m = new Msg<M>(publisherName,message);
        if(!queue.offer(m)){
            // 如果队列满了，从队列中取出消息发送
            update();
            // 清空队列后，再把当前消息放入队列
            queue.offer(m);
        }
    }
    /**
     * @Description: 订阅
     * @param subcriber
     * @return: void
     * @author: leijing
     * @date: 2016年9月29日 下午5:18:43
     */
    public void subcribe(ISubcriber subcriber) {
        subcribers.add(subcriber);
    }
    /**
     * @Description: 退订
     * @param subcriber
     * @return: void
     * @author: leijing
     * @date: 2016年9月29日 下午5:18:43
     */
    public void unSubcribe(ISubcriber subcriber) {
        subcribers.remove(subcriber);
    }
    /**
     * @Description: 发送存储队列所有消息
     * @return: void
     * @author: leijing
     * @date: 2016年9月29日 下午5:20:33
     */
    public void update(){
        Msg m = null;
        while(queue.peek()!= null){
            m=queue.poll();
            this.update(m.getPublisher(),(M)m.getMsg());
        }
    }
    /**
     * @Description: 发送消息
     * @param publisher
     * @param Msg
     * @return: void
     * @author: leijing
     * @date: 2016年9月29日 下午5:14:29
     */
    public void update(String publisher,M Msg) {
        for (ISubcriber subcriber : subcribers) {
            subcriber.update(publisher, Msg);
        }
    }
}
